<?php

require_once 'database_engine/common_engine.php';
require_once 'components/renderer.php';
require_once 'components/utils/string_utils.php';

abstract class ViewProperties
{ }

class PlainTextViewProperties extends ViewProperties
{ }

abstract class GridViewColumn
{
    public function __construct()
    { }

    public abstract function Render(IDataRecord $dataRecord, Renderer $renderer);
}

class CustomRendererColumn extends GridViewColumn
{
    public function Render(IDataRecord $dataRecord, Renderer $renderer)
    {
        return '<a href="http://sqlmaestro.com/">Edit</a>';
    }
}

class FieldBindedGridViewColumn extends GridViewColumn
{
    /**
     * @var ViewProperties
     */
    private $viewProperties;

    /**
     * @var string
     */
    private $fieldName;

    /**
     * @param string $fieldName
     */
    public function __construct($fieldName)
    {
        parent::__construct();
        $this->viewProperties = new PlainTextViewProperties();
        $this->fieldName = $fieldName;
    }

    /**
     * @param ViewProperties $viewProperties
     * @return void
     */
    public function SetViewProperties(ViewProperties $viewProperties)
    {
        $this->viewProperties = $viewProperties;
    }

    /**
     * @return string
     */
    public function GetFieldName()
    {
        return $this->fieldName;
    }

    public function Render(IDataRecord $dataRecord, Renderer $renderer)
    {
        return $dataRecord->GetFieldValueByName($this->GetFieldName());
    }
}

class GridView
{
    /**
     * @var IDataReader
     */
    private $dataReader;
    /**
     * @var Renderer
     */
    private $renderer;

    /**
     * @var string
     */
    private $name;

    /**
     * @var GridViewColumn[]
     */
    private $columns;

    /**
     * @param string $name
     * @param Renderer $renderer
     * @param IDataReader $dataReader
     */
    public function __construct($name, Renderer $renderer, IDataReader $dataReader)
    {
        $this->dataReader = $dataReader;
        $this->renderer = $renderer;
        $this->name = $name;
        $this->columns = array();
    }

    /**
     * @param GridViewColumn $column
     * @return void
     */
    public function AddColumn(GridViewColumn $column)
    {
        $this->columns[] = $column;
    }

    /**
     * @return FieldBindedGridViewColumn
     * @param string $fieldName
     */
    public function AddFieldColumn($fieldName)
    {
        $result = new FieldBindedGridViewColumn($fieldName);
        $this->AddColumn($result);
        return $result;
    }

    /**
     * @return string
     */
    public function RenderGridContainer()
    {
        return $this->renderer->Render('grid_view',
            array(
                'Rows' => array(),
                'Head' => array(),
            )
        );
    }

    private function GetPrimaryKeyAttributes()
    {
        $fieldNames = $this->dataReader->GetFieldNames();
        $primaryKeyFieldValues = array();
        foreach($fieldNames as $fieldName)
            if ($this->dataReader->IsPrimaryKeyField($fieldName))
                $primaryKeyFieldValues[] = $this->dataReader->GetFieldValueByName($fieldName);

        $result = '';
        $i = 1;
        foreach($primaryKeyFieldValues as $value)
        {
            StringUtils::AddStr($result, "pk-value-$i=$value", ' ');
            $i++;
        }
        return $result;
    }

    /**
     * @return array
     */
    private function GetRowData()
    {
        $row = array();
        $cells = array();
        foreach($this->columns as $column)
        {
            $cell = array();
            $cell['Html'] = $column->Render($this->dataReader, $this->renderer);
            $cells[] = $cell;
        }
        $row['Cells'] = $cells;
        
        $row['PrimaryKeyAttributes'] = $this->GetPrimaryKeyAttributes();
        return $row;
    }

    /**
     * @return string
     */
    public function RenderGridRows()
    {
        $rows = array();
        $this->dataReader->Open();
        while ($this->dataReader->Next())
            $rows[] = $this->GetRowData();
        $this->dataReader->Close();
        return $this->renderer->Render('grid_view_rows', array('Rows' => $rows));
    }

    /**
     * @return string
     */
    public function GetName() { return $this->name; }

    /**
     * @static
     * @return string
     */
    public function GetClassTypeName()
    {
        return 'grid-view';
    }

    /**
     * @return void
     */
    public function ProcessRequest()
    {
        if (isset($_GET['filter0field']))
        {
            header('Content-Type: text/xml');
            echo '<?xml version="1.0" encoding="UTF-8"?><response><type>Filtered</type><rows>'.
                    htmlspecialchars($this->RenderGridRows())
                    .'</rows></response>';
        }
        else
        {
            header('Content-Type: text/xml');
            echo '<?xml version="1.0" encoding="UTF-8"?><response><type>OK</type><rows>'.
                    htmlspecialchars($this->RenderGridRows())
                    .'</rows></response>';
        }
    }

}

?>